home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Grab Bag
/
Shareware Grab Bag.iso
/
001
/
fastplot.arc
/
FASTPLOT.ASM
Wrap
Assembly Source File
|
1988-09-14
|
20KB
|
699 lines
TITLE FASTPLOT.ASM
COMMENT *
This program reads both ASCII and binary files from any disk drive of
any IBM/PC/XT or clone. It sends the file contents to the 'COM' port
while maintaining several different handshake protocols. The most common
protocol uses clear to send (CTS, pin 4 of the DB25 connector) to signal
the host when to start/stop sending data. The next most common protocol
uses data set ready (DSR, pin 20 of the DB25 connector) to signal the
host in the same manner. The last method uses X-ON/X-OFF protocol in which
the device sends the host a byte (^S or ^Q) which is used to start/stop
the data flow from the host. All three protocols are supported in this
program. *
;
; Created 30-DEC-86 Richard B. Johnson
; Modification record:
; 04-JAN-86 Added multiple port routines to address 5 COM ports. :RBJ
; 06-JAN-86 Added routine to check for invalid COM port. Checks to
; see if the required UART (8250) is present. For speed,
; this process 'talks' directly to the UART so it's type
; must be known for the routines to work. :RBJ
;
CR EQU 0DH
LF EQU 0AH
BEL EQU 07H
COL_LEN EQU 60 ;100 PERCENT OF THE COLUMN
DTA EQU 80H ;DEFAULT DATA TRANSFER AREA
MS_DOS EQU 21H ;SYSTEM CALLS
KBD EQU 16H ;KEYBOARD ROM VECTOR
VID_ROM EQU 10H ;VIDEO ROM VECTOR
X_ON EQU 'Q'-64 ;PROTOCOL BYTES
X_OFF EQU 'S'-64
CTL_C EQU 'C'-64
; 8250 UART EQUATES
LSTAT EQU 5 ;OFFSET TO LINE STATUS REGISTER
MSTAT EQU 6 ;OFFSET TO MODEM STATUS REGISTER
CTS EQU 00010000B ;CLEAR TO SEND
DSR EQU 00100000B ;DATA SET READY
DR EQU 00000001B ;DATA READY
THRE EQU 00100000B ;TRANSMITTER HOLDING REGISTER READY
BIOS_DATA_SEG EQU 40H ;ROM DATA SEGMENT
;
FILE_BUF STRUC ;DTA STRUCTURE AFTER A 'FIND FIRST' CALL
RES DB 21 DUP (?) ;RESERVED
ATTR DB ? ;FILE ATTRIBUTE FOUND
TIME DW ? ;TIME FILE CREATED
DATE DW ? ;DATE FILE CREATED
SIZEL DW ? ;LOW WORD OF THE FILE SIZE
SIZEH DW ? ;HIGH WORD OF THE FILE SIZE
NAMEF DB ? ;FOUND FILENAME
FILE_BUF ENDS
;
IF1
%OUT [PASS1]
ELSE
%OUT [PASS2]
ENDIF
;
PSEG SEGMENT PARA
ASSUME CS:PSEG, DS:PSEG, ES:PSEG, SS:PSEG
ORG 100H ;'.COM' FILE
MAIN PROC NEAR
JMP SHORT BEGIN
DB 'Copyright (C) 1986, 1987 Richard B. Johnson '
BEGIN: CLD
CLI
MOV AX,CS
MOV DS,AX ;SEGMENT FIXUPS (MS_DOS SHOULD DO IT)
MOV ES,AX
MOV SS,AX
MOV SP,OFFSET STACK ;PUT IT WHERE WE CAN KEEP TRACK
STI
CALL CLS ;CLEAR THE SCREEN
CALL SAV_CUR ;GET CURSOR TYPE
MOV WORD PTR [CURSORT],CX ;SAVE TYPE
CALL GET_CMD ;GET TYPED COMMAND LINE
CALL OPENF ;ATTEMPT TO OPEN THE FILE
JNC OPNOK ;GOOD OPEN
PUSH SI ;SAVE FILENAME
MOV SI,OFFSET NOFILE ;POINT TO 'NO FILE'
CALL PNUL ;PRINT TO SCREEN
POP SI ;RESTORE FILENAME
CALL PNUL ;PRINT TO SCREEN
MOV SI,OFFSET CRLF ;END OF LINE
CALL PNUL ;PRINT TOO
JMP FINIS ;AND EXIT
OPNOK: MOV DH,6 ;SEVENTH LINE
MOV DL,CNTR
CALL POS_CUR ;SET CURSOR POSITION
MOV SI,OFFSET DIAL ;POINT TO THE SIRING
CALL PNUL ;WRITE TO SCREEN
INC DH ;NEXT LINE
CALL POS_CUR ;SET CURSOR
MOV SI,OFFSET DIAL1 ;POINT TO NEXT LINE OF TEXT
CALL PNUL ;PRINT TO SCREEN
INC DH ;READY NEXT LINE
CALL POS_CUR ;SET CURSOR THERE
MOV SI,OFFSET DIAL2 ;POINT TO 'RULER'
CALL PNUL ;PRINT TO SCREEN
MOV WORD PTR [RULER],DX ;SAVE THAT LOCATION
CALL GET_SIZE ;GET FILE SIZE
MOV DX,WORD PTR [FINAL_H] ;READY FOR DIVIDE
MOV AX,WORD PTR [FINAL_L] ;GET FINAL NUMBER
MOV BX,COL_LEN ;GET LENGTH OF THE SCALE
MOV WORD PTR [RUN_BX],BX ;GET WRITES TO SCREEN
DIV BX ;AX= NUMBER OF ITERATIONS
MOV WORD PTR [WMASKL],AX ;SAVE IN MEMORY
MOV DX,WORD PTR [RULER] ;GET 'HOME' LOCATION
ADD DH,5 ;FIVE LINES
CALL POS_CUR ;PUT CURSOR THERE
MOV SI,OFFSET READY ;POINT TO 'GET' PLOTTER READY
CALL PNUL ;PRINT TO THE SCREEN
PAUSE: CALL KEY ;WAIT FOR RESPONSE
JZ PAUSE ;CONTUNUE TO LOOP
CMP AL,CTL_C ;SEE IF AN ABORT
JNZ GO ;NOPE
CALL CLOSEF ;YES, CLOSE THE FILE
MOV SI,OFFSET ABORTED ;POINT TO THE STRING
CALL PNUL ;PRINT TO SCREEN
JMP FINIS ;EXIT
GO: CALL KILL_CUR ;KILL THE CURSOR
MOV DX,WORD PTR [RULER] ;GET 'HOME' POSITION
ADD DH,5 ;ADD FIVE LINES
CALL POS_CUR ;PUT CURSOR THERE
MOV SI,OFFSET WORKING ;POINT TO THE PROMPT STRING
CALL PNUL ;PRINT TO THE SCREEN
CONT: CALL STATUS ;SHOW OUTPUT BYTE COUNT
CALL READF ;READ THE FILE
TEST AX,AX ;ANY BYTES READ?
JNZ OUTPUT ;YES
CALL CLOSEF ;NO, CLOSE THE FILE
MOV SI,OFFSET DONE ;POINT TO 'END OF FILE'
CALL PNUL ;PRINT TO THE SCREEN
JMP FINIS ;AND EXIT
OUTPUT: MOV CX,AX ;BYTE COUNT
MOV SI,OFFSET BUFFER ;WHERE THE DATA IS
CALL COMOUT ;OUTPUT TO THE SELECTED COM PORT
JMP SHORT CONT ;AND CONTINUE
MAIN ENDP
;
; Get communications port address. BX= index into table.
; Check to see if adapter is present. Report errors and exit if unavailable.
;
GET_PORT PROC NEAR
PUSH DS ;SAVE DATA SEGMENT
MOV AX,BIOS_DATA_SEG ;WHERE THE BIOS KEEPS ADDRESSES
MOV DS,AX ;FIRST PAGE
MOV DX,WORD PTR [BX] ;GET COM PORT LOCATION
POP DS ;RESTORE SEGMENT
MOV WORD PTR [PORT],DX ;SAVE IN LOCAL AREA
ADD DX,2 ;OFFSET TO INTERRUPT IDENT REGIS
IN AL,DX ;GET STATUS
TEST AL,11111000B ;CHECK FOR AN 8250 UART
JZ MAYBE ;COULD BE A REAL UART
NOUART: MOV SI,OFFSET BADUART ;NOT AN 8250 UART
CALL PNUL ;PRINT TO SCREEN
SHR BX,1 ;DIVIDE BY TWO (RESTORE BIAS)
MOV AL,BL
ADD AL,'0'+1 ;RESTORE BIAS
CALL CON_OUT ;OUTPUT THE BYTE
MOV SI,OFFSET NFIND ;POINT TO STRING
CALL PNUL ;PRINT TO SCREEN
JMP FINIS ;EXIT
MAYBE: ADD DX,3 ;OFFSET TO LINE STATUS REGISTER
MOV CX,-1 ;TEMP TIMER
RESPON: IN AL,DX ;GET UART STATUS
TEST AL,THRE ;SEE IF TX SHIFT REGIS EMPTY
JNZ UARTOK ;YES, PERHAPS A UART AFTER ALL
LOOP RESPON ;WAIT A BIT
JMP SHORT NOUART
UARTOK: RET
GET_PORT ENDP
;
; Print string addressed by SI until a null.
;
PNUL PROC NEAR
LODSB ;GET A BYTE
TEST AL,AL ;IS IT A NULL?
JZ PDONE ;YES, DONE
CALL CON_OUT ;NO, SEND IT OUT
JMP SHORT PNUL ;CONTINUE
PDONE: RET
PNUL ENDP
;
; Parse the command line. Print 'HELP' if command line is not present or isn't
; correct.
;
GET_CMD PROC NEAR
MOV SI,DTA ;COMMAND LINE BUFFER
LODSB ;GET BYTES TYPED
TEST AL,AL ;CHECK FOR NOTHING
JZ NOWAY ;NO COMMAND LINE
CBW
MOV BX,AX ;NEED AN INDEX REGISTER
MOV BYTE PTR [SI+BX],0 ;THIS WILL BE THE END OF FILENAME
INC SI ;GET BY THE SPACE
LODSB ;GET PROTOCOL
AND AL,95 ;CONVERT TO UPPER CASE
MOV BYTE PTR [PROTO],CTS ;ASSUME CLEAR TO SEND
CMP AL,'C' ;CORRECT?
JZ WASOK ;YES
MOV BYTE PTR [PROTO],DSR ;ASSUME DATA SET READY
CMP AL,'D' ;CORRECT?
JZ WASOK ;YES
MOV BYTE PTR [PROTO],0FFH ;ASSUME X-ON/X-OFF
CMP AL,'X' ;IS IT XON/XOFF?
JZ WASOK ;YES
NOWAY: MOV SI,OFFSET HELP ;NONE OF ABOVE, PRINT HELP
CALL PNUL ;PRINT TO SCREEN
JMP FINIS ;EXIT
WASOK: LODSB ;GET NEXT BYTE
MOV CX,BX ;SAVE INDEX
XOR BX,BX ;ASSUME COM PORT 1
CMP AL,' ' ;WAS IT A SPACE?
JZ USE1 ;WAS JUST A SPACE
SUB AL,'0'+1 ;SUBTRACT ASCII BIAS
JC NOWAY ;NOT A CORRECT PORT NUMBER
CMP AL,5 ;FOUR PORTS MAX
JNC NOWAY ;TOO HIGH A PORT NUMBER
MOV BL,AL ;USE AS AN INDEX
INC SI ;FILENAME FOLLOWS
USE1: MOV WORD PTR [FNAME],SI ;SAVE FILENAME ADDRESS
ADD BX,BX ;TIMES TWO
CALL GET_PORT
MOV BX,CX ;RESTORE INDEX
RET
GET_CMD ENDP
;
; Output the buffer contents addressed by SI to the communications port
; respecting the various protocols.
;
COMOUT PROC NEAR
CMP BYTE PTR [PROTO],0FFH ;SEE IF X-ON/X-OFF
JZ XON
AGAIN: CALL CHECK ;CHECK FOR AN ABORT
CALL MOD_STAT ;GET MODEM STATUS
TEST AL,BYTE PTR [PROTO] ;SEE IF OK TO TRANSMIT
JNZ NOWAIT ;YES, IT'S OK
PUSH CX ;SAVE COUNT
CALL SAV_CUR ;SAVE CURSOR POSITION
PUSH SI ;SAVE LOCATION
MOV SI,OFFSET SYNC ;POINT TO STRING
MOV WORD PTR [LSPRP],SI ;SAVE FOR NOW
CALL PNUL ;PRINT ON THE SCREEN
POP SI ;RESTORE LOCATION
CALL RES_CURP ;RESTORE CURSOR POSITION
NOTYET: CALL CHECK ;CHECK FOR AN ABORT
CALL MOD_STAT
TEST AL,BYTE PTR [PROTO] ;SEE IF IT'S OK YET
JZ NOTYET ;NOT YET
CALL SAV_CUR ;SAVE CURSOR
PUSH SI ;SAVE LOCATION
MOV SI,OFFSET RESUME ;POINT TO THE STRING
MOV WORD PTR [LSPRP],SI ;SAVE FOR NOW
CALL PNUL ;PRINT TO SCREEN
POP SI ;RESTORE LOCATION
CALL RES_CURP ;RESTORE CURSOR POSITION
POP CX ;RESTORE COUNT
JMP SHORT NOWAIT ;OK TO CONTINUE
;
XON: CALL CHECK ;CHECK WAIT/ABORT FROM CONSOLE
CALL COMIN ;CHECK INPUT PORT
JZ NOWAIT ;NOTHING HERE YET
CMP AL,X_OFF ;WANT TO WAIT
JNZ NOWAIT ;NOPE, MUST BE GARBAGE
CALL WAITX ;YES, WAIT FOR X_ON
NOWAIT: CALL BYTOUT ;OUTPUT THE BYTE
LOOP COMOUT ;CONTINUE
RET
COMOUT ENDP
;
; Get any possible byte from the 'COM' port.
;
COMIN PROC NEAR
MOV DX,WORD PTR [PORT] ;GET COM PORT ADDRESS
PUSH DX ;SAVE FOR NOW
ADD DX,LSTAT ;ADD IN OFFSET TO LINE STATUS
IN AL,DX ;GET STATUS BYTE
POP DX ;RESTORE BASE PORT ADDRESS
TEST AL,DR ;SEE IF DATA READY
JZ NODAT ;WAIT FOREVER UNTIL READY
IN AL,DX ;GET BYTE
INC DX ;MAKE CERTAIN NO ZERO
NODAT: RET
COMIN ENDP
;
; Check the modem status of the UART.
;
MOD_STAT PROC NEAR
MOV DX,WORD PTR [PORT] ;GET PORT ADDRESS
ADD DX,MSTAT ;ADD IN OFFSET TO MODEM STATUS
IN AL,DX ;GET STATUS BYTE
RET
MOD_STAT ENDP
;
; Output a byte from the buffer addressed by SI to the 'COM1' UART.
;
BYTOUT PROC NEAR
MOV DX,WORD PTR [PORT] ;GET COM PORT ADDRESS
PUSH DX ;SAVE FOR NOW
ADD DX,LSTAT ;ADD IN OFFSET TO LINE STATUS
FOREVER:
IN AL,DX ;GET STATUS BYTE
TEST AL,THRE ;WAIT FOR HOLDING REGISTER EMPTY
JNZ EMPTY ;WAIT UNTIL READY
CALL STATUS ;UART NOT READY, SHOW STATUS
JMP SHORT FOREVER ;CONTINUE
EMPTY: POP DX ;RESTORE BASE PORT ADDRESS
LODSB ;GET BYTE FROM BUFFER
OUT DX,AL ;AND OUTPUT THE BYTE
INC WORD PTR [XMITL] ;UP THE BYTE COUNT
JNZ BYPASS ;NO OVERFLOW
INC WORD PTR [XMITH] ;UPDATE THE COUNT
BYPASS: CALL SCALE
RET
BYTOUT ENDP
;
; Wait for the host to send a X-ON. Abort from the keyboard is possible.
;
WAITX PROC NEAR ;WAIT FOR X-ON FROM HOST
PUSH SI ;SAVE LOCATION
PUSH CX ;SAVE COUNT
CALL SAV_CUR ;SAVE CURSOR POSITION
MOV SI,OFFSET SYNC ;POINT TO STRING
MOV WORD PTR [LSPRP],SI ;SAVE FOR NOW
CALL PNUL ;PRINT TO SCREEN
CALL RES_CURP ;RESTORE CURSOR POSITION
WAIT0: CALL CHECK ;CHECK FOR ABORT
CALL COMIN ;GET INPUT BYTE
CMP AL,X_ON ;READY TO RESUME?
JNZ WAIT0 ;NOPE
CALL SAV_CUR ;SAVE CURSOR POSITION
MOV SI,OFFSET RESUME ;POINT TO STRING
MOV WORD PTR [LSPRP],SI ;SAVE FOR NOW
CALL PNUL ;PRINT TO SCREEN
CALL RES_CURP ;RESTORE THE CURSOR POSITION
POP CX ;RESTORE COUNT
POP SI ;RESTORE LOCATION
RET
WAITX ENDP
;
; Check for a possible abort from the keyboard. Pause for a second key
; pressed if there is any keyboard input.
;
CHECK PROC NEAR
PUSH SI ;SAVE LOCATION
PUSH CX ;SAVE COUNT
CALL KEY ;CHECK FOR A KEY PRESSED
JZ NOKEY ;NO KEY WAS PRESSED
CMP AL,CTL_C ;CHECK FOR CONTROL C
JZ QUIT ;WAS CONTROL C
CALL SAV_CUR ;SAVE CURRENT CURSOR POSITION
MOV SI,OFFSET HOLDING ;POINT TO STRING
CALL PNUL ;PRINT IT
CALL RES_CURP ;RESTORE THE CURSOR POSITION
HOLD PROC NEAR ;WAIT FOR A KEY TO BE PRESSED
CALL KEY ;CHECK KEYBOARD
JZ HOLD ;NOTHING PRESSED
CMP AL,CTL_C ;CHECK FOR CONTROL C
JZ QUIT ;ABORT
MOV SI,WORD PTR [LSPRP] ;GET LAST STRING
CALL PNUL ;PRINT IT
CALL RES_CURP ;RESTORE CURSOR POSITION
NOKEY: POP CX ;RESTORE COUNT
POP SI ;RESTORE LOCATION
RET ;END OF HOLD
QUIT: POP CX ;LEVEL STACK CX=COUNT
POP SI ;BUFFER LOCATION
POP AX ;RETURN ADDRESS
MOV SI,OFFSET ABORTED
CALL PNUL
JMP FINIS
HOLD ENDP
CHECK ENDP
;
; Get any input from the keyboard.
;
KEY PROC NEAR
MOV AH,1 ;CHECK IF CHARACTER WAITING
INT KBD
JZ NOPE ;NOTHING HERE
MOV AH,0 ;YES, GET THE CHARACTER
INT KBD
TEST AX,AX ;INSURE NO ZERO FLAG
NOPE: RET
KEY ENDP
;
; Print transmit status to the screen.
;
STATUS PROC NEAR
PUSH SI ;SAVE INDEX, DESTROYED BY ASCII
PUSH DX ;SAVE ALSO
PUSH CX
CALL SAV_CUR
MOV DX,WORD PTR [XMITH] ;GET HIGH WORD OF BYTES TRANSMITTED
MOV AX,WORD PTR [XMITL] ;GET LOW WORD OF BYTES TRANSMITTED
CALL ASCII
CALL RES_CURP ;RESTORE CURSOR POSITION
POP CX
POP DX
POP SI
RET
STATUS ENDP
;
; Open the file pointed to by [FNAME]
;
OPENF PROC NEAR
MOV DX,WORD PTR [FNAME] ;POINT TO FILENAME
XOR CX,CX ;NORMAL FILE
MOV AX,3D00H ;OPEN FOR READING
INT MS_DOS
MOV WORD PTR [HANDLE],AX ;SAVE THE HANDLE
JNC FOUND ;FILE WAS FOUND
MOV BYTE PTR [SI+BX-2],0 ;FOR A BAD FILENAME
RET
FOUND: MOV AH,4EH ;GET FILE CHARACTERISTICS
INT MS_DOS ;WILL RETURN IN DTA [80H]
RET
OPENF ENDP
;
; Close the file.
;
CLOSEF PROC NEAR
MOV AX,3E00H ;CLOSE FILE FUNCTION
MOV BX,WORD PTR [HANDLE] ;GET THE FILE HANDLE
INT MS_DOS
RET
CLOSEF ENDP
;
; Read the file. Read as much into memory as possible within the 64k
; segment allowed to speed file access. For most files, only one read
; will be required.
;
READF PROC NEAR
MOV DX,OFFSET BUFFER ;WHERE TO PUT FILE DATA
MOV CX,-1 ;64 K TO READ
SUB CX,DX ;MINUS SPACE USED FOR PROGRAM
MOV BX,WORD PTR [HANDLE] ;GET FILE HANDLE
MOV AX,3F00H ;READ THE FILE
INT MS_DOS
RET
READF ENDP
;
; End the program, return to MS_DOS. Return status OK even if aborted.
;
FINIS PROC NEAR
CALL RES_CUR ;RESTORE CURSOR TYPE
MOV DH,23 ;24TH LINE
MOV DL,0 ;FIRST COLUMN
CALL POS_CUR ;CURSOR AT BOTTOM OF SCREEN
MOV AX,4C00H
INT MS_DOS
FINIS ENDP
;
GET_SIZE PROC NEAR
MOV DX,WORD PTR [RULER]
ADD DH,2 ;TWO LINES
CALL POS_CUR ;PUT CURSOR THERE
MOV SI,OFFSET HOWBIG
CALL PNUL
MOV SI,DTA + NAMEF ;POINT TO THE FILENAME
CALL PNUL
MOV SI,OFFSET IS
CALL PNUL
MOV SI,DTA
MOV DX,WORD PTR [SI+ SIZEH] ;GET PART OF FILE SIZE
MOV AX,WORD PTR [SI+ SIZEL] ;GET LOW PART OF FILE SIZE
MOV WORD PTR [FINAL_L],AX
MOV WORD PTR [FINAL_H],DX
CALL ASCII
MOV SI,OFFSET LONG
CALL PNUL
RET
GET_SIZE ENDP
;
; Print double precision number in DX:AX
;
ASCII PROC NEAR
MOV SI,0000 ;LEADING ZERO FLAG
MOV CX,3B9AH ;GET BILLIONS
MOV BX,0CA00H
CALL SUBTR ;SUBTRACT THEM OUT
CALL COMMA ;PUT IN A COMMA
MOV CX,05F5H ;GET HUNDRED-MILLIONS
MOV BX,0E100H
CALL SUBTR ;SUBTRACT THEM OUT
MOV CX,0098H ;GET TEN-MILLIONS
MOV BX,9680H
CALL SUBTR ;SUBTRACT THEM OUT
MOV CX,000FH ;GET MILLIONS
MOV BX,4240H
CALL SUBTR ;SUBTRACT THEM OUT
CALL COMMA ;PUT IN A COMMA
MOV CX,0001H ;GET HUNDRED-THOUSANDS
MOV BX,86A0H
CALL SUBTR ;SUNTRACT THEM OUT
MOV CX,0000H ;GET TEN-THOUSANDS
MOV BX,2710H
CALL SUBTR ;SUBTRACT THEM OUT
MOV CX,0000H ;GET THOUSANDS
MOV BX,03E8H
CALL SUBTR ;SUNTRACT THEM OUT
CALL COMMA ;PUT IN A COMMA
MOV CX,0000H ;GET HUNDREDS
MOV BX,0064H
CALL SUBTR ;SUBTRACT THEM OUT
MOV CX,0000H ;GET TENS
MOV BX,000AH
CALL SUBTR ;SUBTRACT THEM OUT
ADD AL,'0'
JMP SHORT CON_OUT ;IMPLIED RETURN
;
SUBTR: MOV DI,'0'-1 ;START WITH ONE LESS THAN ASCII BIAS
SUBTR1: INC DI ;COUNTER
SUB AX,BX ;DWORD SUBTRACTION
SBB DX,CX
JNB SUBTR1 ;CONTINUE UNTIL CARRY
ADD AX,BX ;ONE TOO MANY, ADD BACK
ADC DX,CX
PUSH AX ;SAVE FOR NOW
MOV AX,DI ;GET COUNT
CMP SI,0 ;SEE IF ANY BYTES HAVE BEEN PRINTED
JNZ SUBTR2 ;NO, CAN'T BE A LEADING ZERO
CMP AL,'0' ;IS IS A ZERO?
JZ SUBTR3 ;YES, DON'T PRINT LEADING ZEROS
INC SI ;NO SET FLAG
SUBTR2: CALL CON_OUT
SUBTR3: POP AX
RET
;
COMMA: CMP SI,0 ;SEE IF ANY BYTES HAVE BEEN PRINTED
JZ PASS ;NO, THEN NO COMMAS
PUSH AX
MOV AL,','
CALL CON_OUT
POP AX
PASS: RET
ASCII ENDP
;
; Using the 'faster than DOS' video ROM routine, output a byte to the screen.
;
CON_OUT PROC NEAR
PUSH BX
PUSH DX
ZERO: MOV AH,14 ;WRITE CHARACTER TO SCREEN,
MOV BX,7 ;NORMAL ATTRIBUTE
INT VID_ROM
EXIT: POP DX
POP BX
RET
CON_OUT ENDP
;
SAV_CUR PROC NEAR
MOV AH,3 ;GET CURSOR POSITION, TYPE
MOV BH,0 ;PAGE ZERO
INT VID_ROM
MOV WORD PTR [CURSORP],DX ;SAVE POSITION
RET
SAV_CUR ENDP
;
; Kill the cursor by making it so tiny you can't see it!!
;
KILL_CUR PROC NEAR
MOV CX,-1
MOV AH,1
INT VID_ROM
RET
KILL_CUR ENDP
;
RES_CUR PROC NEAR
MOV AH,1
MOV CX,WORD PTR [CURSORT] ;GET OLD CURSOR TYPE
INT VID_ROM ;RESTORE THE CURSOR
RET
RES_CUR ENDP
;
RES_CURP PROC NEAR
MOV DX,WORD PTR [CURSORP] ;GET OLD CURSOR POSITION
;
POS_CUR PROC NEAR ;PUT CURSOR AT DH=ROW, DL=COLUMN
MOV AH,2
MOV BH,0 ;PAGE ZERO
INT VID_ROM
RET
POS_CUR ENDP
RES_CURP ENDP
;
ADVANCE PROC NEAR
CALL SAV_CUR ;SAVE PRESENT POSITION
MOV DX,WORD PTR [RULER] ;GET LAST 'RULER' POSITION
INC WORD PTR [RULER] ;READY NEXT
CALL POS_CUR ;PUT CURSOR AT LAST CHARACTER POS
MOV AL,'=' ;COVER UP THE '>'
CALL CON_OUT ;WRITE TO SCREEN
MOV AL,'>' ;ADD AN ARROW
CALL CON_OUT ;WRITE TO SCREEN
CALL RES_CURP ;RESTORE CURSOR
RET
ADVANCE ENDP
;
SCALE PROC NEAR
PUSH CX ;SAVE COUNT
DEC WORD PTR [RUN_BX]
JNZ NOADV
MOV AX,WORD PTR [WMASKL] ;GET NEW PARAMS
MOV WORD PTR [RUN_BX],AX ;INTO THE 'INSIDE' RUNNING COUNT
CALL ADVANCE ;ADVANCE THE POINTER
NOADV: POP CX ;RESTORE BYTE COUNT
RET
SCALE ENDP
;
CLS PROC NEAR
MOV AX,0500H ;SELECT ACTIVE PAGE
INT VID_ROM
MOV AX,0600H ;SCROLL ACTIVE PAGE AWAY
XOR CX,CX ;UPPER LEFT
MOV BH,7 ;ATTRIBUTE
MOV DH,24 ;25TH ROW
MOV DL,79 ;80TH COLUMN
INT VID_ROM
MOV DH,1 ;SECOND LINE LINE FROM TOP
MOV DL,CENTER ;WHATEVER CENTERS THE STRING
CALL POS_CUR ;CURSOR HOME
MOV SI,OFFSET LOGO ;POINT TO SIGNON
CALL PNUL ;PRINT TO THE SCREEN
MOV DX,0500H ;SIXTH LINE FROM TOP
CALL POS_CUR ;CURSOR HOME
RET
CLS ENDP
;
; Data area.
;
PROTO DB ? ;MASK BYTE FOR PROTOCOL
EVEN
HANDLE DW ? ;OPEN FILE HANDLE
FNAME DW ? ;LOCATION OF THE FILENAME
CURSORT DW ? ;SAVE CURSOR TYPE
CURSORP DW ? ;SAVE CURSOR POSITION
PORT DW ? ;COM PORT
XMITH DW 0 ;NUMBER OF BYTES TRANSMITTED (HIGH WORD)
XMITL DW 0 ;NUMBER OF BYTES TRANSMITTED (LOW WORD)
LSPRP DW RESUME ;LAST STATUS WORD
FINAL_L DW ? ;FINAL NUMBER
FINAL_H DW ?
RUN_BX DW ?
WMASKL DW ?
CURSOR DW ? ;SAVE CURSOR
RULER DW ?
;
DONE DB CR,LF,' The plot is finished.',CR,LF,BEL,0
ABORTED DB CR,LF,' Aborted! ',CR,LF,BEL,0
HOLDING DB CR,LF,' [Holding] ',0
RESUME DB CR,LF,' ',0
SYNC DB CR,LF,' [TTYSYNC]',0
DB 16 DUP ('STACK ')
STACK LABEL WORD
;
; From here on up to offset 64k is used for the file buffer. The data
; is overwritten since it's only used before the file is read into the
; buffer.
;
BUFFER LABEL BYTE
DIAL DB ' Percent completion',0
DIAL1 DB '0 10 20 30 40 50 60 '
DB '70 80 90 100',0
DIAL2 DB 10 DUP ("+-----")
DB "+"
DB 0
CNTR EQU (40 - ($ - DIAL2)/2)
LOGO DB 'uDESIGNS IBM/PC/XT Plotter Driver',0
CENTER EQU (40 - ($ - LOGO)/2)
HOWBIG DB 'The plot file ',0
IS DB ' is ',0
LONG DB ' bytes in length.'
CRLF DB CR,LF,0
READY DB 'Hit any key when the plotter is ready: ',0
WORKING DB ' '
DB CR,LF,' Hit any key to pause.'
DB CR,LF,' Hit any key to resume.'
DB CR,LF,' Hit ^C to abort.'
DB CR,LF,' Bytes transmitted: ',0
BADUART DB CR,LF,' Communications adapter COM',0
NFIND DB ': not present.'
DB CR,LF,0
NOFILE DB CR,LF,' File not found: ',0
HELP DB CR,LF,'FASTPLOT [C,D,X]<PORT> [FILENAME]'
DB CR,LF,'C = CLEAR TO SEND protocol (pin 4 of DB25 connector)'
DB CR,LF,'D = DATASET READY protocol (pin 20 of DB25 connector)'
DB CR,LF,'X = X-ON/X-OFF protocol'
DB CR,LF,'PORT<OPTIONAL> = 1, 2, 3, 4 (Default is COM1:)'
DB CR,LF,'FILENAME = any \PATH\FILENAME combination.'
DB CR,LF,'Examples:'
DB CR,LF,'Fastplot x orcad.plt'
DB CR,LF,'Fastplot x2 orcad.plt'
DB CR,LF,'Fastplot c2 orcad.plt'
DB CR,LF,'Fastplot d4 c:\draft\orcad.plt'
DB CR,LF,0
PSEG ENDS
END MAIN